<!DOCTYPE html>
<html lang="ru-RU">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>Руководство по тестированию Vue приложений (Vue.js 2)</title>
    <meta name="description" content="">
    <link rel="icon" href="https://lmiller1990.github.io/vue-testing-handbook/img/favicon.png">
  <meta property="og:title" content="Vue Testing Handbook">
  <meta property="og:description" content="Vue testing handbook">
  <meta property="og:type" content="website">
  <meta property="og:url" content="https://lmiller1990.github.io/vue-testing-handbook/">
  <meta property="og:image" content="https://lmiller1990.github.io/vue-testing-handbook/img/og.png">
    
    <link rel="preload" href="/vue-testing-handbook/assets/css/0.styles.99f2ca3b.css" as="style"><link rel="preload" href="/vue-testing-handbook/assets/js/app.14051834.js" as="script"><link rel="preload" href="/vue-testing-handbook/assets/js/3.119a321e.js" as="script"><link rel="preload" href="/vue-testing-handbook/assets/js/2.94957ecd.js" as="script"><link rel="preload" href="/vue-testing-handbook/assets/js/56.40ebbbe6.js" as="script"><link rel="prefetch" href="/vue-testing-handbook/assets/js/10.7b1750c8.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/100.87c02eb0.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/101.9f86f8af.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/102.7cf5b3b5.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/103.9a447cc0.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/104.d960f455.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/105.42aa8c19.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/106.fa067e24.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/107.f6145328.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/108.4251a9d9.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/109.6e04b4aa.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/11.c9a15d65.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/110.203be49f.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/111.e66d4c1a.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/112.d5cf2637.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/113.0e1df8ea.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/114.b1d0a5f5.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/115.d21ab6a2.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/116.e13d34ff.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/117.532bedf9.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/118.b99c8d4d.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/119.97666be8.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/12.8ec4d737.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/120.e5fbc47b.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/121.2d6cedde.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/122.7dc3c3fc.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/123.82fcb804.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/124.affd46d3.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/125.10d1ddcb.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/126.8ca1978a.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/127.7b76e158.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/128.e0d8fdce.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/129.e861e49f.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/13.96ee585a.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/130.474092c4.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/131.71e4509c.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/132.b48fe96d.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/133.9268758a.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/134.6a042ef6.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/135.6df261f9.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/136.8aab4165.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/137.60d15690.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/138.29f827fd.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/139.e8db710e.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/14.522b77b9.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/140.8a3b2b26.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/141.cd5f96df.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/142.04a47072.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/143.ac0cb5e1.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/144.c69a73ac.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/15.2f00de2d.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/16.d120a376.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/17.9260e267.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/18.4e3a9d5e.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/19.bfe7cfa3.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/20.52828530.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/21.4d92035b.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/22.49a88bda.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/23.79de1f16.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/24.f45f108e.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/25.48371e8a.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/26.bc7a5470.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/27.49bfeced.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/28.b697055e.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/29.0ef469da.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/30.bd209efe.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/31.ddf8aa10.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/32.95ec3267.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/33.52cf0ebc.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/34.73b1ca03.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/35.be79f171.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/36.52a4dcd2.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/37.a02e83c0.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/38.2a809ae1.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/39.31de0194.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/4.a86536d1.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/40.4a3cfcb7.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/41.db485265.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/42.8c4375ac.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/43.2f241bb5.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/44.43539973.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/45.619b76a6.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/46.00e17cc1.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/47.faf51fac.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/48.840de9e5.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/49.3410da74.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/5.d3ebdf21.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/50.647913c0.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/51.4990b428.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/52.85ff4209.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/53.7bbf915a.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/54.1fc8316d.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/55.374436d3.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/57.40d9cc46.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/58.37ab0bcf.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/59.8df2efac.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/6.637082cf.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/60.326b4bdd.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/61.449fcfe0.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/62.f05ac3d6.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/63.e1723f7e.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/64.5b9e17ef.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/65.52e8ce24.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/66.cbdf653b.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/67.522e5bfd.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/68.1c27735b.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/69.1f5624e9.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/7.43089f9d.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/70.49fd6b50.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/71.20acc429.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/72.715f4620.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/73.ac123d7d.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/74.59a869d0.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/75.772485ad.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/76.b887e73a.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/77.70e54ee3.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/78.2306c3e7.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/79.e01a6cd1.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/8.4c4cdaa7.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/80.c12fc82f.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/81.44ef90b7.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/82.ff3143a2.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/83.22084435.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/84.485c66f4.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/85.d8afef97.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/86.2ba55e96.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/87.d5642266.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/88.3ad1f8ac.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/89.e370d2fc.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/9.a0f31be6.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/90.2c039dfb.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/91.2c1dd586.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/92.571cd8ae.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/93.b88ae6f6.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/94.16000348.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/95.79a96428.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/96.c86f8cad.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/97.bc1d6c91.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/98.34c6a547.js"><link rel="prefetch" href="/vue-testing-handbook/assets/js/99.e1174558.js">
    <link rel="stylesheet" href="/vue-testing-handbook/assets/css/0.styles.99f2ca3b.css">
  </head>
  <body>
    <div id="app" data-server-rendered="true"><div class="theme-container"><header class="navbar"><div class="sidebar-button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" role="img" viewBox="0 0 448 512" class="icon"><path fill="currentColor" d="M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z"></path></svg></div> <a href="/vue-testing-handbook/ru/" class="home-link router-link-active"><!----> <span class="site-name">Руководство по тестированию Vue приложений (Vue.js 2)</span></a> <div class="links"><div class="search-box"><input aria-label="Search" autocomplete="off" spellcheck="false" value=""> <!----></div> <nav class="nav-links can-hide"><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="Select language" class="dropdown-title"><span class="title">Переводы</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/vue-testing-handbook/composition-api.html" class="nav-link">English</a></li><li class="dropdown-item"><!----> <a href="/vue-testing-handbook/v3/composition-api.html" class="nav-link">v3</a></li><li class="dropdown-item"><!----> <a href="/vue-testing-handbook/ja/composition-api.html" class="nav-link">日本語</a></li><li class="dropdown-item"><!----> <a href="/vue-testing-handbook/ru/composition-api.html" class="nav-link router-link-exact-active router-link-active">Русский (Vue.js 2)</a></li><li class="dropdown-item"><!----> <a href="/vue-testing-handbook/v3/ru/composition-api.html" class="nav-link">Русский (Vue.js 3)</a></li><li class="dropdown-item"><!----> <a href="/vue-testing-handbook/zh-CN/composition-api.html" class="nav-link">简体中文</a></li><li class="dropdown-item"><!----> <a href="/vue-testing-handbook/ko/composition-api.html" class="nav-link">한국어</a></li></ul></div></div> <a href="https://github.com/lmiller1990/vue-testing-handbook" target="_blank" rel="noopener noreferrer" class="repo-link">
    GitHub
    <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></nav></div></header> <div class="sidebar-mask"></div> <aside class="sidebar"><a href="https://vuejs-course.com/" target="_blank"><img id="ad" src="https://raw.githubusercontent.com/lmiller1990/vue-testing-handbook/master/src/.vuepress/public/composition.png" alt="vuejs-course banner"></a> <br> <div class="info"><small>
    Hi! Get $10 off my
    <a href="https://vuejs-course.com/" target="_blank">new</a> <a href="https://vuejs-course.com/" target="_blank">course</a> <a href="https://vuejs-course.com/" target="_blank">on</a> <a href="https://vuejs-course.com/" target="_blank">Vue.js 3</a>,
    <a href="https://vuejs-course.com/" target="_blank">TypeScript and</a>,
    <a href="https://vuejs-course.com/" target="_blank">testing</a>,
    with the discount code VUEJS_COURSE_10_OFF.
    </small></div> <nav class="nav-links"><div class="nav-item"><div class="dropdown-wrapper"><button type="button" aria-label="Select language" class="dropdown-title"><span class="title">Переводы</span> <span class="arrow right"></span></button> <ul class="nav-dropdown" style="display:none;"><li class="dropdown-item"><!----> <a href="/vue-testing-handbook/composition-api.html" class="nav-link">English</a></li><li class="dropdown-item"><!----> <a href="/vue-testing-handbook/v3/composition-api.html" class="nav-link">v3</a></li><li class="dropdown-item"><!----> <a href="/vue-testing-handbook/ja/composition-api.html" class="nav-link">日本語</a></li><li class="dropdown-item"><!----> <a href="/vue-testing-handbook/ru/composition-api.html" class="nav-link router-link-exact-active router-link-active">Русский (Vue.js 2)</a></li><li class="dropdown-item"><!----> <a href="/vue-testing-handbook/v3/ru/composition-api.html" class="nav-link">Русский (Vue.js 3)</a></li><li class="dropdown-item"><!----> <a href="/vue-testing-handbook/zh-CN/composition-api.html" class="nav-link">简体中文</a></li><li class="dropdown-item"><!----> <a href="/vue-testing-handbook/ko/composition-api.html" class="nav-link">한국어</a></li></ul></div></div> <a href="https://github.com/lmiller1990/vue-testing-handbook" target="_blank" rel="noopener noreferrer" class="repo-link">
    GitHub
    <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a></nav>  <ul class="sidebar-links"><li><a href="/vue-testing-handbook/ru/" class="sidebar-link">Введение</a></li><li><a href="/vue-testing-handbook/ru/setting-up-for-tdd.html" class="sidebar-link">Подготовка к TDD</a></li><li><a href="/vue-testing-handbook/ru/rendering-a-component.html" class="sidebar-link">Отрисовка компонентов</a></li><li><a href="/vue-testing-handbook/ru/components-with-props.html" class="sidebar-link">Тестирование входных параметров</a></li><li><a href="/vue-testing-handbook/ru/computed-properties.html" class="sidebar-link">Вычисляемые свойства</a></li><li><a href="/vue-testing-handbook/ru/simulating-user-input.html" class="sidebar-link">Симулирование пользовательского ввода</a></li><li><a href="/vue-testing-handbook/ru/testing-emitted-events.html" class="sidebar-link">Тестирование пользовательских событий</a></li><li><a href="/vue-testing-handbook/ru/mocking-global-objects.html" class="sidebar-link">Мокаем глобальные объекты</a></li><li><a href="/vue-testing-handbook/ru/stubbing-components.html" class="sidebar-link">Заглушки для компонентов</a></li><li><a href="/vue-testing-handbook/ru/finding-elements-and-components.html" class="sidebar-link">Поиск элементов и компонентов</a></li><li><a href="/vue-testing-handbook/ru/testing-vuex.html" class="sidebar-link">Тестирование Vuex</a></li><li><a href="/vue-testing-handbook/ru/vuex-mutations.html" class="sidebar-link">Vuex - Мутации</a></li><li><a href="/vue-testing-handbook/ru/vuex-actions.html" class="sidebar-link">Vuex - Действия</a></li><li><a href="/vue-testing-handbook/ru/vuex-getters.html" class="sidebar-link">Vuex - Геттеры</a></li><li><a href="/vue-testing-handbook/ru/vuex-in-components.html" class="sidebar-link">Vuex в компонентах - $state и геттеры</a></li><li><a href="/vue-testing-handbook/ru/vuex-in-components-mutations-and-actions.html" class="sidebar-link">Vuex в компонентах - мутации и действия</a></li><li><a href="/vue-testing-handbook/ru/vue-router.html" class="sidebar-link">Vue Router</a></li><li><a href="/vue-testing-handbook/ru/composition-api.html" class="active sidebar-link">Composition API</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/vue-testing-handbook/ru/composition-api.html#the-composition-api" class="sidebar-link">The Composition API</a></li><li class="sidebar-sub-header"><a href="/vue-testing-handbook/ru/composition-api.html#компонент" class="sidebar-link">Компонент</a></li><li class="sidebar-sub-header"><a href="/vue-testing-handbook/ru/composition-api.html#тестирование-сообщения-из-входных-параметров" class="sidebar-link">Тестирование сообщения из входных параметров</a></li><li class="sidebar-sub-header"><a href="/vue-testing-handbook/ru/composition-api.html#тестирование-кnика-по-кнопке" class="sidebar-link">Тестирование клика по кнопке</a></li><li class="sidebar-sub-header"><a href="/vue-testing-handbook/ru/composition-api.html#закnючение" class="sidebar-link">Заключение</a></li></ul></li><li><a href="/vue-testing-handbook/ru/reducing-boilerplate-in-tests.html" class="sidebar-link">Уменьшаем шаблонный код</a></li><li><a href="/vue-testing-handbook/ru/jest-mocking-modules.html" class="sidebar-link">Jest - мокаем модули</a></li></ul> </aside> <main class="page"> <div class="theme-default-content content__default"><div class="custom-block tip"><p class="custom-block-title">Это руководство было написано для Vue.js 2 и Vue Test Utils v1.</p> <p>Версия для Vue.js 3 <a href="/v3/ru">здесь</a>.</p></div> <h2 id="the-composition-api"><a href="#the-composition-api" class="header-anchor">#</a> The Composition API</h2> <p>Vue 3 предоставит новое API для создания компонентов – <a href="https://vue-composition-api-rfc.netlify.com/#basic-example" target="_blank" rel="noopener noreferrer">Composition API<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a>. Для сбора отзывов от пользователей, команда Vue выложила плагин, который позволяет попробовать это API во Vue 2. Вы можете найти его <a href="https://github.com/vuejs/composition-api" target="_blank" rel="noopener noreferrer">здесь<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a>.</p> <p>Тестирование компонента, созданного с помощью Composition API ничем не должно отличаться от тестирования обычного компонента, так как мы тестируем не реализацию, а поведение, то что будет на выходе. (<em>что</em> делает компонент, а не <em>как</em> он это делает). В этой статье будет разобран пример небольшого компонента, использующего Composition API во Vue 2, и то, как похоже тестирование такого компонента в сравнении с обычным.</p> <p>Исходный код для тестов на этой странице можно найти <a href="https://github.com/lmiller1990/vue-testing-handbook/tree/master/demo-app/tests/unit/CompositionApi.spec.js" target="_blank" rel="noopener noreferrer">здесь<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a>.</p> <h2 id="компонент"><a href="#компонент" class="header-anchor">#</a> Компонент</h2> <p>Ниже можно увидеть базовый пример Composition API. Если вы что-то не понимаете, <a href="https://vue-composition-api-rfc.netlify.com/" target="_blank" rel="noopener noreferrer">прочитайте RFC<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></a> или воспользуетесь гуглом; есть множество ресурсов про Composition API.</p> <div class="language-html extra-class"><pre class="language-html"><code><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>template</span><span class="token punctuation">&gt;</span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>message<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>{{ uppercasedMessage }}<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>div</span> <span class="token attr-name">class</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>count<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>
      Счётчик: {{ state.count }}
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
    <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>button</span> <span class="token attr-name">@click</span><span class="token attr-value"><span class="token punctuation">=</span><span class="token punctuation">&quot;</span>increment<span class="token punctuation">&quot;</span></span><span class="token punctuation">&gt;</span></span>Увеличить<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>button</span><span class="token punctuation">&gt;</span></span>
  <span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>div</span><span class="token punctuation">&gt;</span></span>
<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>template</span><span class="token punctuation">&gt;</span></span>

<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>script</span><span class="token punctuation">&gt;</span></span><span class="token script"><span class="token language-javascript">
<span class="token keyword">import</span> Vue <span class="token keyword">from</span> <span class="token string">'vue'</span>
<span class="token keyword">import</span> VueCompositionApi <span class="token keyword">from</span> <span class="token string">'@vue/composition-api'</span>

Vue<span class="token punctuation">.</span><span class="token function">use</span><span class="token punctuation">(</span>VueCompositionApi<span class="token punctuation">)</span>

<span class="token keyword">import</span> <span class="token punctuation">{</span> 
  reactive<span class="token punctuation">,</span>
  computed
<span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">'@vue/composition-api'</span>

<span class="token keyword">export</span> <span class="token keyword">default</span> <span class="token punctuation">{</span>
  name<span class="token punctuation">:</span> <span class="token string">'CompositionApi'</span><span class="token punctuation">,</span>

  props<span class="token punctuation">:</span> <span class="token punctuation">{</span>
    message<span class="token punctuation">:</span> <span class="token punctuation">{</span>
      type<span class="token punctuation">:</span> String
    <span class="token punctuation">}</span>
  <span class="token punctuation">}</span><span class="token punctuation">,</span>

  <span class="token function">setup</span><span class="token punctuation">(</span><span class="token parameter">props</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
    <span class="token keyword">const</span> state <span class="token operator">=</span> <span class="token function">reactive</span><span class="token punctuation">(</span><span class="token punctuation">{</span>
      count<span class="token punctuation">:</span> <span class="token number">0</span>
    <span class="token punctuation">}</span><span class="token punctuation">)</span>

    <span class="token keyword">const</span> <span class="token function-variable function">increment</span> <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
      state<span class="token punctuation">.</span>count <span class="token operator">+=</span> <span class="token number">1</span>
    <span class="token punctuation">}</span>

    <span class="token keyword">return</span> <span class="token punctuation">{</span>
      state<span class="token punctuation">,</span>
      increment<span class="token punctuation">,</span>
      uppercasedMessage<span class="token punctuation">:</span> <span class="token function">computed</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> props<span class="token punctuation">.</span>message<span class="token punctuation">.</span><span class="token function">toUpperCase</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
    <span class="token punctuation">}</span>
  <span class="token punctuation">}</span>
<span class="token punctuation">}</span>
</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>script</span><span class="token punctuation">&gt;</span></span>
</code></pre></div><p>Здесь нам нужно протестировать две вещи:</p> <ol><li><p>Увеличивается ли <code>state.count</code> на 1 при клике на кнопку &quot;Увеличить&quot;?</p></li> <li><p>Верно ли отрисовывается сообщение из входных параметров (трансформируется в верхний регистр)?</p></li></ol> <h2 id="тестирование-сообщения-из-входных-параметров"><a href="#тестирование-сообщения-из-входных-параметров" class="header-anchor">#</a> Тестирование сообщения из входных параметров</h2> <p>Тестирование правильно ли отрисовалось сообщение – банально. Мы просто используем <code>propsData</code> для установки значения параметра как описано <a href="/vue-testing-handbook/ru/components-with-props.html">здесь</a>.</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">import</span> <span class="token punctuation">{</span> mount <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">&quot;@vue/test-utils&quot;</span>

<span class="token keyword">import</span> CompositionApi <span class="token keyword">from</span> <span class="token string">&quot;@/components/CompositionApi.vue&quot;</span>

<span class="token function">describe</span><span class="token punctuation">(</span><span class="token string">&quot;CompositionApi&quot;</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  <span class="token function">it</span><span class="token punctuation">(</span><span class="token string">&quot;отрисовывает сообщение&quot;</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
    <span class="token keyword">const</span> wrapper <span class="token operator">=</span> <span class="token function">mount</span><span class="token punctuation">(</span>CompositionApi<span class="token punctuation">,</span> <span class="token punctuation">{</span>
      propsData<span class="token punctuation">:</span> <span class="token punctuation">{</span>
        message<span class="token punctuation">:</span> <span class="token string">&quot;Тестируем composition API&quot;</span>
      <span class="token punctuation">}</span>
    <span class="token punctuation">}</span><span class="token punctuation">)</span>

    <span class="token function">expect</span><span class="token punctuation">(</span>wrapper<span class="token punctuation">.</span><span class="token function">find</span><span class="token punctuation">(</span><span class="token string">&quot;.message&quot;</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">text</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">toBe</span><span class="token punctuation">(</span><span class="token string">&quot;ТЕСТИРУЕМ COMPOSITION API&quot;</span><span class="token punctuation">)</span>
  <span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span>
</code></pre></div><p>Как и ожидалось, это было очень просто – несмотря на то, что мы применили composition компонент, API для тестирования и сам подход не поменялся. Вы можете полностью поменять реализацию, но тесты трогать не придётся. Помните – нужно тестировать данные на выходе (обычно это отрисованный HTML) на основе переданных входных данных (входные параметры, пользовательские события), а не реализацию.</p> <h2 id="тестирование-кnика-по-кнопке"><a href="#тестирование-кnика-по-кнопке" class="header-anchor">#</a> Тестирование клика по кнопке</h2> <p>Написание теста, гарантирующего увеличение <code>state.count</code> при клике на кнопку – также просто. Обратите внимание, что в тесте используется <code>async</code>; о том, зачем это здесь необходимо читайте в главе <a href="/vue-testing-handbook/ru/simulating-user-input.html#writing-the-test">симулирование пользовательского ввода</a>.</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">import</span> <span class="token punctuation">{</span> mount <span class="token punctuation">}</span> <span class="token keyword">from</span> <span class="token string">&quot;@vue/test-utils&quot;</span>

<span class="token keyword">import</span> CompositionApi <span class="token keyword">from</span> <span class="token string">&quot;@/components/CompositionApi.vue&quot;</span>

<span class="token function">describe</span><span class="token punctuation">(</span><span class="token string">&quot;CompositionApi&quot;</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
  <span class="token function">it</span><span class="token punctuation">(</span><span class="token string">&quot;увеличивает счётчик при клике на кнопку&quot;</span><span class="token punctuation">,</span> <span class="token keyword">async</span> <span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">=&gt;</span> <span class="token punctuation">{</span>
    <span class="token keyword">const</span> wrapper <span class="token operator">=</span> <span class="token function">mount</span><span class="token punctuation">(</span>CompositionApi<span class="token punctuation">,</span> <span class="token punctuation">{</span>
      propsData<span class="token punctuation">:</span> <span class="token punctuation">{</span> message<span class="token punctuation">:</span> <span class="token string">''</span> <span class="token punctuation">}</span>
    <span class="token punctuation">}</span><span class="token punctuation">)</span>

    <span class="token keyword">await</span> wrapper<span class="token punctuation">.</span><span class="token function">find</span><span class="token punctuation">(</span><span class="token string">'button'</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">trigger</span><span class="token punctuation">(</span><span class="token string">'click'</span><span class="token punctuation">)</span>

    <span class="token function">expect</span><span class="token punctuation">(</span>wrapper<span class="token punctuation">.</span><span class="token function">find</span><span class="token punctuation">(</span><span class="token string">&quot;.count&quot;</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">text</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">toBe</span><span class="token punctuation">(</span><span class="token string">&quot;Счётчик: 1&quot;</span><span class="token punctuation">)</span>
  <span class="token punctuation">}</span><span class="token punctuation">)</span>
<span class="token punctuation">}</span><span class="token punctuation">)</span>
</code></pre></div><p>Опять не очень интересно – мы <code>триггерим</code> событие клика и проверяем, что счётчик увеличился.</p> <h2 id="закnючение"><a href="#закnючение" class="header-anchor">#</a> Заключение</h2> <p>В статье продемонстрировалось как тестирование компонента с использованием Composition API ничем не отличает от тестирования обычного компонента. Идеи и концепты одни и те же. Главное, что нужно понять – мы пишем тест и делаем проверки на основе входящих и выходящих данных.</p> <p>Должна быть предусмотрена возможность рефакторинга обычных компонентов на компоненты с Composition API без надобности изменений тестов. Если вы обнаружили, что нужно переписывать тесты при рефакторинге – вероятней всего вы тестируете <em>реализацию</em>, а не данные на выходе.</p> <p>Несмотря на новые интересные возможности, которые даёт Composition API, совсем не обязательно его использовать прямо сейчас. Однако не зависимо от вашего выбора, помните, что хорошие модульные тесты проверяют конечное состояние компонента и не учитывают детали реализации.</p></div> <footer class="page-edit"><div class="edit-link"><a href="https://github.com/lmiller1990/vue-testing-handbook/edit/master/ru/composition-api.md" target="_blank" rel="noopener noreferrer">Редактировать эту страницу на GitHub</a> <svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg></div> <div class="last-updated"><span class="prefix">Последнее обновление:</span> <span class="time">15.09.2020, 01:18:30</span></div></footer> <div class="page-nav"><p class="inner"><span class="prev">
      ←
      <a href="/vue-testing-handbook/ru/vue-router.html" class="prev">Vue Router</a></span> <span class="next"><a href="/vue-testing-handbook/ru/reducing-boilerplate-in-tests.html">Уменьшаем шаблонный код</a>
      →
    </span></p></div> </main></div><div class="global-ui"></div></div>
    <script src="/vue-testing-handbook/assets/js/app.14051834.js" defer></script><script src="/vue-testing-handbook/assets/js/3.119a321e.js" defer></script><script src="/vue-testing-handbook/assets/js/2.94957ecd.js" defer></script><script src="/vue-testing-handbook/assets/js/56.40ebbbe6.js" defer></script>
  </body>
</html>
